import { createDeck, Card } from '../game/Card.js';
import { Player } from '../game/Player.js';
import { generateSessionId, formatError, formatSuccess } from '../utils/helpers.js';
import logger from '../utils/logger.js';

class MultiplayerGameEngine {
  constructor(databaseService) {
    this.db = databaseService;
    this.activeSessions = new Map(); // sessionId -> gameSession
    this.roomSessions = new Map(); // roomId -> sessionId
  }

  /**
   * 开始游戏
   */
  async startGame(roomId, playerData) {
    try {
      if (this.roomSessions.has(roomId)) {
        return formatError('GAME_ALREADY_STARTED', '游戏已经开始');
      }

      if (!playerData || playerData.length !== 3) {
        return formatError('INVALID_PLAYERS', '需要3名玩家');
      }

      const sessionId = generateSessionId();

      // 创建玩家对象（保留AI与座位信息）
      const players = playerData.map((p, index) => {
        const isAI = p?.isAI ?? p?.is_ai ?? false;
        const seatIndex = p?.seatIndex ?? p?.seat_index ?? index;
        const player = new Player(p.id, p.name, isAI, seatIndex);
        player.isReady = p?.isReady ?? p?.is_ready ?? player.isReady;
        return player;
      });

      // 创建游戏会话
      const gameSession = {
        id: sessionId,
        roomId,
        players,
        currentPlayerIndex: 0,
        currentRound: 1,
        roundCards: [],
        collectedCards: {},
        gameStatus: 'playing',
        waitingForCollection: false,
        roundWinner: null,
        firstPlayer: null,
        isFirstRound: true,
        kouLeStatus: {
          isActive: false,
          initiator: null,
          decisions: {},
          xuanPlayers: [],
          riskMultiplier: 2
        },
        actionSequence: 0,
        startedAt: new Date()
      };

      // 初始化收牌数
      players.forEach(player => {
        gameSession.collectedCards[player.id] = 0;
      });

      // 异步发牌
      await this.dealCardsAsync(gameSession);

      // 检查无相情况
      const wuxiangResult = this.checkWuxiang(gameSession);
      if (wuxiangResult.hasWuxiang) {
        // 重新发牌
        await this.dealCardsAsync(gameSession);
        // 再次检查（理论上很少连续无相）
        const secondCheck = this.checkWuxiang(gameSession);
        if (secondCheck.hasWuxiang) {
          return formatError('CONTINUOUS_WUXIANG', '连续无相，请稍后重试');
        }
      }

      // 随机选择首发玩家
      gameSession.currentPlayerIndex = Math.floor(Math.random() * 3);
      gameSession.firstPlayer = players[gameSession.currentPlayerIndex];

      // 保存到内存和数据库
      this.activeSessions.set(sessionId, gameSession);
      this.roomSessions.set(roomId, sessionId);

      const gameStateData = this.serializeGameState(gameSession);
      await this.db.createGameSession({
        id: sessionId,
        roomId,
        gameState: gameStateData,
        currentPlayerIndex: gameSession.currentPlayerIndex,
        currentRound: gameSession.currentRound
      });

      logger.info(`游戏会话创建: ${sessionId} (房间: ${roomId})`);

      return formatSuccess({
        sessionId,
        gameState: this.getGameStateForPlayers(gameSession)
      }, '游戏开始成功');

    } catch (error) {
      logger.error(`开始游戏失败: ${error.message}`);
      return formatError('SERVER_ERROR', '服务器内部错误');
    }
  }

  /**
   * 异步发牌
   */
  async dealCardsAsync(gameSession) {
    const deck = createDeck();

    // 洗牌
    for (let i = deck.length - 1; i > 0; i--) {
      const j = Math.floor(Math.random() * (i + 1));
      [deck[i], deck[j]] = [deck[j], deck[i]];
    }

    // 清空玩家手牌
    gameSession.players.forEach(player => {
      player.cards = [];
    });

    // 发牌，每人8张
    for (let i = 0; i < 24; i++) {
      const playerIndex = i % 3;
      gameSession.players[playerIndex].cards.push(deck[i]);
    }

    // 排序手牌
    gameSession.players.forEach(player => {
      player.cards = this.smartSortCards(player.cards);
    });
  }

  /**
   * 智能排序卡牌
   */
  smartSortCards(cards) {
    // 按牌力从大到小排序
    const sorted = [...cards].sort((a, b) => b.power - a.power);

    // 调整顺序，确保对子相邻
    const result = [];
    const used = new Set();

    for (let i = 0; i < sorted.length; i++) {
      if (used.has(sorted[i].id)) continue;

      result.push(sorted[i]);
      used.add(sorted[i].id);

      // 查找配对的牌
      for (let j = i + 1; j < sorted.length; j++) {
        if (used.has(sorted[j].id)) continue;

        if (sorted[i].canPairWith(sorted[j])) {
          result.push(sorted[j]);
          used.add(sorted[j].id);
          break;
        }
      }
    }

    return result;
  }

  /**
   * 检查无相情况
   */
  checkWuxiang(gameSession) {
    const keyCardNames = ['红相', '黑相', '红尔', '黑尔'];

    for (let player of gameSession.players) {
      const hasKeyCard = player.cards.some(card =>
        keyCardNames.includes(card.displayName)
      );

      if (!hasKeyCard) {
        return {
          hasWuxiang: true,
          player: player,
          missingCards: keyCardNames
        };
      }
    }

    return { hasWuxiang: false };
  }

  /**
   * 玩家出牌
   */
  async playCards(roomId, playerId, cards) {
    try {
      const session = this.getSessionByRoomId(roomId);
      if (!session) {
        return formatError('GAME_NOT_FOUND', '游戏不存在');
      }

      if (session.gameStatus !== 'playing') {
        return formatError('GAME_NOT_PLAYING', '游戏未在进行中');
      }

      if (session.waitingForCollection) {
        return formatError('WAITING_COLLECTION', '请先收牌');
      }

      const player = session.players.find(p => p.id === playerId);
      if (!player) {
        return formatError('PLAYER_NOT_FOUND', '玩家不存在');
      }

      // 验证是否为当前玩家回合
      if (session.players[session.currentPlayerIndex].id !== playerId) {
        return formatError('NOT_YOUR_TURN', '不是你的回合');
      }

      // 验证出牌
      const validation = this.validatePlay(session, player, cards);
      if (!validation.valid) {
        return formatError('INVALID_PLAY', validation.message);
      }

      // 执行出牌
      const cardObjects = cards.map(cardData => Card.fromJSON(cardData));
      
      // 从手牌中移除
      cardObjects.forEach(card => {
        const index = player.cards.findIndex(c => c.id === card.id);
        if (index !== -1) {
          player.cards.splice(index, 1);
        }
      });

      // 记录出牌
      session.roundCards.push({
        player: player,
        cards: cardObjects,
        power: this.calculatePlayPower(cardObjects),
        sequence: session.actionSequence++
      });

      // 记录操作
      await this.recordAction(session, playerId, 'play_cards', {
        cards: cardObjects.map(c => c.toJSON())
      });

      // 下一个玩家回合
      this.nextTurn(session);

      // 保存状态
      await this.saveGameState(session);

      logger.info(`玩家出牌: ${player.name} (${roomId})`);

      return formatSuccess({
        gameState: this.getGameStateForPlayers(session)
      }, '出牌成功');

    } catch (error) {
      logger.error(`出牌失败: ${error.message}`);
      return formatError('SERVER_ERROR', '服务器内部错误');
    }
  }

  /**
   * 玩家扣牌
   */
  async passTurn(roomId, playerId, discardCards = null) {
    try {
      const session = this.getSessionByRoomId(roomId);
      if (!session) {
        return formatError('GAME_NOT_FOUND', '游戏不存在');
      }

      const player = session.players.find(p => p.id === playerId);
      if (!player) {
        return formatError('PLAYER_NOT_FOUND', '玩家不存在');
      }

      if (session.players[session.currentPlayerIndex].id !== playerId) {
        return formatError('NOT_YOUR_TURN', '不是你的回合');
      }

      if (session.roundCards.length === 0) {
        return formatError('CANNOT_PASS_FIRST', '第一个出牌不能扣牌');
      }

      const firstPlay = session.roundCards[0];
      const requiredCount = firstPlay.cards.length;

      // 验证强制出牌规则
      if (this.hasValidPlay(session, player)) {
        return formatError('MUST_PLAY', '有能出的牌，不能扣牌');
      }

      // 处理扣牌
      let cardsToRemove = [];
      if (Array.isArray(discardCards) && discardCards.length > 0) {
        if (discardCards.length > requiredCount) {
          return formatError('INVALID_PASS_COUNT', `扣牌数量必须为${requiredCount}张`);
        }

        const seenIds = new Set();
        for (const cardData of discardCards) {
          if (!cardData || !cardData.id) {
            return formatError('INVALID_CARD_DATA', '扣牌数据无效');
          }

          if (seenIds.has(cardData.id)) {
            continue; // 忽略重复选择的同一张牌
          }
          seenIds.add(cardData.id);

          const index = player.cards.findIndex(c => c.id === cardData.id);
          if (index === -1) {
            return formatError('CARD_NOT_FOUND', '选择的牌不存在或已被使用');
          }

          const [removed] = player.cards.splice(index, 1);
          if (removed) {
            cardsToRemove.push(removed);
          }
        }
      }

      // 补足缺少的扣牌数量，自动从手牌末尾选择最小牌
      while (cardsToRemove.length < requiredCount && player.cards.length > 0) {
        const card = player.cards.pop();
        if (card) {
          cardsToRemove.push(card);
        }
      }

      if (cardsToRemove.length !== requiredCount) {
        return formatError('INVALID_PASS_COUNT', `扣牌需要${requiredCount}张牌`);
      }

      // 记录扣牌
      session.roundCards.push({
        player: player,
        cards: [],
        power: 0,
        passed: true,
        discardedCards: cardsToRemove,
        sequence: session.actionSequence++
      });

      // 记录操作
      await this.recordAction(session, playerId, 'pass', {
        discardedCards: cardsToRemove.map(c => c.toJSON())
      });

      // 下一个玩家回合
      this.nextTurn(session);

      // 保存状态
      await this.saveGameState(session);

      logger.info(`玩家扣牌: ${player.name} (${roomId})`);

      return formatSuccess({
        gameState: this.getGameStateForPlayers(session)
      }, '扣牌成功');

    } catch (error) {
      logger.error(`扣牌失败: ${error.message}`);
      return formatError('SERVER_ERROR', '服务器内部错误');
    }
  }

  /**
   * 收牌
   */
  async collectCards(roomId, collectorId = null) {
    try {
      const session = this.getSessionByRoomId(roomId);
      if (!session) {
        return formatError('GAME_NOT_FOUND', '游戏不存在');
      }

      if (!session.waitingForCollection) {
        return formatError('NOT_COLLECTING', '当前不在收牌阶段');
      }

      // 计算赢家和收牌数
      this.calculateRoundWinner(session);
      const roundWinnerId = session.roundWinner ? session.roundWinner.id : null;
      const completedRound = session.currentRound;
      
      if (session.roundWinner) {
        const cardsPerPlayer = session.roundCards[0].cards.length;
        const cardsToCollect = cardsPerPlayer * 3;
        session.collectedCards[session.roundWinner.id] += cardsToCollect;

        // 设置下轮首发
        const winnerIndex = session.players.findIndex(p => p.id === session.roundWinner.id);
        session.currentPlayerIndex = winnerIndex;
      }

      // 清空本轮记录
      session.roundCards = [];
      session.waitingForCollection = false;
      session.roundWinner = null;
      session.currentRound++;
      session.isFirstRound = false;

      // 检查游戏是否结束
      const gameOver = this.checkGameOver(session);
      if (gameOver) {
        await this.endGame(session);
      }

      // 记录操作
      const actionPlayerId = collectorId || roundWinnerId || session.players[session.currentPlayerIndex]?.id;
      
      if (actionPlayerId) {
        await this.recordAction(session, actionPlayerId, 'collect', {
          round: completedRound
        });
      } else {
        logger.warn(`收牌操作缺少有效玩家ID: ${session.roomId}`);
      }

      // 保存状态
      await this.saveGameState(session);

      logger.info(`收牌完成: ${roomId}, 轮次: ${completedRound}`);

      return formatSuccess({
        gameState: this.getGameStateForPlayers(session)
      }, '收牌成功');

    } catch (error) {
      logger.error(`收牌失败: ${error.message}`);
      return formatError('SERVER_ERROR', '服务器内部错误');
    }
  }

  /**
   * 发起扣了
   */
  async initiateKouLe(roomId, playerId) {
    try {
      const session = this.getSessionByRoomId(roomId);
      if (!session) {
        return formatError('GAME_NOT_FOUND', '游戏不存在');
      }

      const player = session.players.find(p => p.id === playerId);
      if (!player) {
        return formatError('PLAYER_NOT_FOUND', '玩家不存在');
      }

      if (session.players[session.currentPlayerIndex].id !== playerId) {
        return formatError('NOT_YOUR_TURN', '不是你的回合');
      }

      if (session.kouLeStatus.isActive) {
        return formatError('KOULE_ACTIVE', '扣了决策进行中');
      }

      // 设置扣了状态
      session.kouLeStatus = {
        isActive: true,
        initiator: playerId,
        decisions: { [playerId]: 'kou' },
        xuanPlayers: [],
        riskMultiplier: 2
      };

      // 保存状态
      await this.saveGameState(session);

      logger.info(`扣了发起: ${player.name} (${roomId})`);

      return formatSuccess({
        gameState: this.getGameStateForPlayers(session)
      }, '扣了发起成功');

    } catch (error) {
      logger.error(`发起扣了失败: ${error.message}`);
      return formatError('SERVER_ERROR', '服务器内部错误');
    }
  }

  /**
   * 响应扣了
   */
  async respondToKouLe(roomId, playerId, decision) {
    try {
      const session = this.getSessionByRoomId(roomId);
      if (!session) {
        return formatError('GAME_NOT_FOUND', '游戏不存在');
      }

      if (!session.kouLeStatus.isActive) {
        return formatError('KOULE_INACTIVE', '当前没有扣了决策');
      }

      if (playerId === session.kouLeStatus.initiator) {
        return formatError('ALREADY_DECIDED', '您已经选择了扣了');
      }

      if (session.kouLeStatus.decisions[playerId]) {
        return formatError('ALREADY_RESPONDED', '您已经做出了选择');
      }

      // 记录决策
      session.kouLeStatus.decisions[playerId] = decision;
      
      if (decision === 'xuan') {
        session.kouLeStatus.xuanPlayers.push(playerId);
      }

      // 检查是否所有人都已决策或有人选择"宣"
      const allPlayerIds = session.players.map(p => p.id);
      const decidedCount = Object.keys(session.kouLeStatus.decisions).length;
      const hasXuan = session.kouLeStatus.xuanPlayers.length > 0;

      let result = null;
      if (hasXuan || decidedCount === allPlayerIds.length) {
        result = this.resolveKouLe(session);
      }

      // 保存状态
      await this.saveGameState(session);

      const player = session.players.find(p => p.id === playerId);
      logger.info(`扣了响应: ${player.name} -> ${decision} (${roomId})`);

      return formatSuccess({
        gameState: this.getGameStateForPlayers(session),
        kouLeResult: result
      }, `选择${decision === 'kou' ? '扣了' : '宣'}成功`);

    } catch (error) {
      logger.error(`响应扣了失败: ${error.message}`);
      return formatError('SERVER_ERROR', '服务器内部错误');
    }
  }

  /**
   * 解决扣了结果
   */
  resolveKouLe(session) {
    const xuanCount = session.kouLeStatus.xuanPlayers.length;

    if (xuanCount === 0) {
      // 全部扣了，需要重新发牌
      session.kouLeStatus.isActive = false;
      return {
        type: 'redeal',
        message: '所有人都选择扣了，需要重新发牌'
      };
    } else {
      // 有人宣，游戏继续
      session.kouLeStatus.isActive = false;
      const xuanPlayerNames = session.kouLeStatus.xuanPlayers
        .map(id => session.players.find(p => p.id === id)?.name || id)
        .join('、');
      
      return {
        type: 'continue',
        message: `${xuanPlayerNames}选择了宣，游戏继续`,
        xuanPlayers: session.kouLeStatus.xuanPlayers
      };
    }
  }

  /**
   * 验证出牌
   */
  validatePlay(session, player, cards) {
    if (!cards || cards.length === 0) {
      return { valid: false, message: '至少要出一张牌' };
    }

    // 验证玩家是否拥有这些牌
    const cardObjects = cards.map(cardData => Card.fromJSON(cardData));
    const hasAllCards = cardObjects.every(card =>
      player.cards.some(c => c.id === card.id)
    );
    
    if (!hasAllCards) {
      return { valid: false, message: '您没有这些牌' };
    }

    // 验证出牌组合
    if (cardObjects.length === 2) {
      if (!cardObjects[0].canPairWith(cardObjects[1])) {
        return { valid: false, message: '这两张牌不能组成对子' };
      }
    } else if (cardObjects.length > 2) {
      // 检查多张曲曲
      const ququRanks = ['J', 'Q', 'K'];
      const allQuqu = cardObjects.every(c => ququRanks.includes(c.rank));
      if (!allQuqu) {
        return { valid: false, message: '只有同色曲曲可以一起出多张' };
      }

      const redSuits = ['hearts', 'diamonds'];
      const firstIsRed = redSuits.includes(cardObjects[0].suit);
      const allSameColor = cardObjects.every(c => {
        const isRed = redSuits.includes(c.suit);
        return isRed === firstIsRed;
      });

      if (!allSameColor) {
        return { valid: false, message: '多张曲曲必须颜色相同' };
      }
    }

    // 如果本轮已有出牌，检查跟牌规则
    if (session.roundCards.length > 0) {
      const firstPlay = session.roundCards[0];
      
      if (cardObjects.length !== firstPlay.cards.length) {
        return { valid: false, message: `必须出${firstPlay.cards.length}张牌` };
      }

      const currentMaxPower = Math.max(...session.roundCards
        .filter(p => !p.passed)
        .map(p => p.power));

      const playPower = this.calculatePlayPower(cardObjects);

      // 特殊规则：大小王对和红尔对不分胜负
      if (playPower === currentMaxPower && playPower === 125) {
        return { valid: false, message: '大小王对和红尔对不分胜负，不能出牌' };
      }

      if (playPower <= currentMaxPower) {
        return { valid: false, message: '出的牌必须大于桌面上的牌' };
      }
    }

    return { valid: true };
  }

  /**
   * 检查是否有有效出牌
   */
  hasValidPlay(session, player) {
    if (session.roundCards.length === 0) return true;

    const firstPlay = session.roundCards[0];
    const requiredCount = firstPlay.cards.length;
    const currentMaxPower = Math.max(...session.roundCards
      .filter(p => !p.passed)
      .map(p => p.power));

    // 查找所有可能的出牌组合
    const possiblePlays = this.findPossiblePlays(player, requiredCount);
    
    return possiblePlays.some(play => {
      const power = this.calculatePlayPower(play);
      if (power === currentMaxPower && power === 125) {
        return false; // 特殊规则
      }
      return power > currentMaxPower;
    });
  }

  /**
   * 查找可能的出牌组合
   */
  findPossiblePlays(player, requiredCount) {
    const possiblePlays = [];

    if (requiredCount === 1) {
      // 单牌
      player.cards.forEach(card => {
        possiblePlays.push([card]);
      });
    } else if (requiredCount === 2) {
      // 对子
      for (let i = 0; i < player.cards.length - 1; i++) {
        for (let j = i + 1; j < player.cards.length; j++) {
          if (player.cards[i].canPairWith(player.cards[j])) {
            possiblePlays.push([player.cards[i], player.cards[j]]);
          }
        }
      }
    } else {
      // 多张曲曲
      const ququRanks = ['J', 'Q', 'K'];
      const redQu = player.cards.filter(c => 
        ququRanks.includes(c.rank) && ['hearts', 'diamonds'].includes(c.suit)
      );
      const blackQu = player.cards.filter(c => 
        ququRanks.includes(c.rank) && ['spades', 'clubs'].includes(c.suit)
      );

      if (redQu.length >= requiredCount) {
        this.getCombinations(redQu, requiredCount).forEach(combo => {
          possiblePlays.push(combo);
        });
      }
      if (blackQu.length >= requiredCount) {
        this.getCombinations(blackQu, requiredCount).forEach(combo => {
          possiblePlays.push(combo);
        });
      }
    }

    return possiblePlays;
  }

  /**
   * 获取组合
   */
  getCombinations(arr, size) {
    const result = [];

    function combine(start, combo) {
      if (combo.length === size) {
        result.push([...combo]);
        return;
      }

      for (let i = start; i < arr.length; i++) {
        combo.push(arr[i]);
        combine(i + 1, combo);
        combo.pop();
      }
    }

    combine(0, []);
    return result;
  }

  /**
   * 计算出牌牌力
   */
  calculatePlayPower(cards) {
    if (cards.length === 0) return 0;

    if (cards.length === 1) {
      return cards[0].power;
    }

    if (cards.length === 2) {
      const isDaXiaoWangPair = cards.every(c => c.rank === 'joker') &&
                              cards[0].displayName !== cards[1].displayName;
      const isRedErPair = cards.every(c => c.displayName === '红尔');

      if (isDaXiaoWangPair || isRedErPair) {
        return 125; // 特殊牌力
      } else {
        return cards[0].power + 100;
      }
    }

    if (cards.length >= 3) {
      const maxPower = Math.max(...cards.map(c => c.power));
      return maxPower + 200;
    }

    return 0;
  }

  /**
   * 下一个玩家回合
   */
  nextTurn(session) {
    if (session.roundCards.length === 3) {
      // 本轮结束，等待收牌
      session.waitingForCollection = true;
      this.calculateRoundWinner(session);
    } else {
      // 下一个玩家
      session.currentPlayerIndex = (session.currentPlayerIndex + 1) % 3;
    }
  }

  /**
   * 计算本轮赢家
   */
  calculateRoundWinner(session) {
    let winner = null;
    let maxPower = -1;

    session.roundCards.forEach(play => {
      if (!play.passed && play.power > maxPower) {
        maxPower = play.power;
        winner = play.player;
      }
    });

    session.roundWinner = winner;
  }

  /**
   * 检查游戏是否结束
   */
  checkGameOver(session) {
    return session.players.some(player => player.cards.length === 0);
  }

  /**
   * 结束游戏
   */
  async endGame(session) {
    session.gameStatus = 'finished';
    
    // 计算最终结果
    const results = this.calculateGameResults(session);
    session.gameResults = results;

    // 保存最终状态
    await this.saveGameState(session);

    logger.info(`游戏结束: ${session.roomId}`);
  }

  /**
   * 计算游戏结果
   */
  calculateGameResults(session) {
    const results = [];

    session.players.forEach(player => {
      const collected = session.collectedCards[player.id] || 0;
      let level = '不够';
      let coins = 0;

      if (collected >= 18) {
        level = '此了';
        coins = 3;
      } else if (collected >= 15) {
        level = '五了';
        coins = 2;
      } else if (collected >= 9) {
        level = '刚够';
        coins = 1;
      }

      results.push({
        player: player.getSafeInfo(),
        collected,
        level,
        coins
      });
    });

    return { results };
  }

  /**
   * 序列化游戏状态
   */
  serializeGameState(session) {
    return {
      sessionId: session.id,
      roomId: session.roomId,
      players: session.players.map(p => p.toJSON(true)),
      currentPlayerIndex: session.currentPlayerIndex,
      currentRound: session.currentRound,
      roundCards: session.roundCards.map(rc => ({
        player: rc.player.getSafeInfo(),
        cards: rc.cards.map(c => c.toJSON()),
        power: rc.power,
        passed: rc.passed,
        discardedCards: rc.discardedCards ? rc.discardedCards.map(c => c.toJSON()) : undefined,
        sequence: rc.sequence
      })),
      collectedCards: session.collectedCards,
      gameStatus: session.gameStatus,
      waitingForCollection: session.waitingForCollection,
      roundWinner: session.roundWinner ? session.roundWinner.getSafeInfo() : null,
      firstPlayer: session.firstPlayer ? session.firstPlayer.getSafeInfo() : null,
      isFirstRound: session.isFirstRound,
      kouLeStatus: session.kouLeStatus,
      actionSequence: session.actionSequence
    };
  }

  /**
   * 获取适合传输给玩家的游戏状态
   */
  getGameStateForPlayers(session) {
    const baseState = this.serializeGameState(session);
    
    // 为每个玩家定制状态（只包含该玩家的手牌详情）
    return {
      ...baseState,
      players: session.players.map(p => ({
        ...p.getSafeInfo(),
        cards: [], // 手牌信息需要单独发送给对应玩家
        cardCount: p.cards.length
      })),
      // 添加个人手牌字段，由前端根据playerId匹配
      personalCards: session.players.reduce((acc, p) => {
        acc[p.id] = p.cards.map(c => c.toJSON());
        return acc;
      }, {})
    };
  }

  /**
   * 获取游戏状态
   */
  async getGameState(roomId) {
    try {
      const session = this.getSessionByRoomId(roomId);
      if (session) {
        return this.getGameStateForPlayers(session);
      }

      // 从数据库恢复
      const sessionId = this.roomSessions.get(roomId);
      if (sessionId) {
        const dbSession = await this.db.getGameSession(sessionId);
        if (dbSession) {
          const restoredSession = this.deserializeGameState(dbSession);
          this.activeSessions.set(sessionId, restoredSession);
          return this.getGameStateForPlayers(restoredSession);
        }
      }

      return null;
    } catch (error) {
      logger.error(`获取游戏状态失败: ${error.message}`);
      return null;
    }
  }

  /**
   * 反序列化游戏状态
   */
  deserializeGameState(dbSession) {
    const gameState = JSON.parse(dbSession.game_state);
    
    // 重建玩家对象
    const players = gameState.players.map(playerData => {
      const player = Player.fromJSON(playerData);
      player.cards = playerData.cards ? playerData.cards.map(cardData => Card.fromJSON(cardData)) : [];
      return player;
    });

    const session = {
      id: dbSession.id,
      roomId: dbSession.room_id,
      players,
      currentPlayerIndex: gameState.currentPlayerIndex,
      currentRound: gameState.currentRound,
      roundCards: gameState.roundCards.map(rc => ({
        player: players.find(p => p.id === rc.player.id),
        cards: rc.cards.map(cardData => Card.fromJSON(cardData)),
        power: rc.power,
        passed: rc.passed,
        discardedCards: rc.discardedCards ? rc.discardedCards.map(cardData => Card.fromJSON(cardData)) : undefined,
        sequence: rc.sequence
      })),
      collectedCards: gameState.collectedCards,
      gameStatus: gameState.gameStatus,
      waitingForCollection: gameState.waitingForCollection,
      roundWinner: gameState.roundWinner ? players.find(p => p.id === gameState.roundWinner.id) : null,
      firstPlayer: gameState.firstPlayer ? players.find(p => p.id === gameState.firstPlayer.id) : null,
      isFirstRound: gameState.isFirstRound,
      kouLeStatus: gameState.kouLeStatus,
      actionSequence: gameState.actionSequence || 0,
      startedAt: new Date(dbSession.started_at)
    };

    return session;
  }

  /**
   * 保存游戏状态到数据库
   */
  async saveGameState(session) {
    try {
      const gameStateData = this.serializeGameState(session);
      await this.db.updateGameSession(session.id, {
        gameState: gameStateData,
        currentPlayerIndex: session.currentPlayerIndex,
        currentRound: session.currentRound,
        roundCards: session.roundCards,
        collectedCards: session.collectedCards
      });
    } catch (error) {
      logger.error(`保存游戏状态失败: ${error.message}`);
    }
  }

  /**
   * 记录游戏操作
   */
  async recordAction(session, playerId, actionType, actionData) {
    try {
      await this.db.recordGameAction({
        sessionId: session.id,
        playerId,
        actionType,
        actionData,
        roundNumber: session.currentRound,
        sequence: session.actionSequence
      });
    } catch (error) {
      logger.error(`记录游戏操作失败: ${error.message}`);
    }
  }

  /**
   * 通过房间ID获取游戏会话
   */
  getSessionByRoomId(roomId) {
    const sessionId = this.roomSessions.get(roomId);
    return sessionId ? this.activeSessions.get(sessionId) : null;
  }

  /**
   * 清理过期会话
   */
  cleanup() {
    const now = Date.now();
    const expiredSessions = [];

    for (const [sessionId, session] of this.activeSessions.entries()) {
      // 清理2小时前的已结束游戏
      if (session.gameStatus === 'finished' && 
          (now - new Date(session.startedAt).getTime()) > 2 * 60 * 60 * 1000) {
        expiredSessions.push(sessionId);
      }
    }

    for (const sessionId of expiredSessions) {
      const session = this.activeSessions.get(sessionId);
      if (session) {
        this.roomSessions.delete(session.roomId);
        this.activeSessions.delete(sessionId);
        logger.info(`清理过期会话: ${sessionId}`);
      }
    }
  }

  /**
   * 获取统计信息
   */
  getStats() {
    return {
      activeSessions: this.activeSessions.size,
      playingSessions: Array.from(this.activeSessions.values())
        .filter(s => s.gameStatus === 'playing').length,
      finishedSessions: Array.from(this.activeSessions.values())
        .filter(s => s.gameStatus === 'finished').length
    };
  }
}

export default MultiplayerGameEngine;
